home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Tele / C / Comet2.1.3 Folder / Comet / token.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-30  |  11.8 KB  |  579 lines  |  [TEXT/????]

  1. /* token.c is the shell of the token handling routine, which is filled 
  2.  *  in with the routines executed when an action described by a token entry 
  3.  *  is found.
  4.  */
  5.  
  6. /*
  7.     Copyright Cornell University 1986.  All rights are reserved.
  8.  
  9. */
  10.  
  11. #include <em.h>
  12.  
  13. #include <menudefs.h>
  14. #include <rcodes.h>
  15. #include <h19.h>
  16. #include <3270.h>
  17. #include <macdefs.h>
  18. #include <resdefs.h>
  19.  
  20.  
  21. char scrapzeroed;            /* has scrap been zeroed yet? */
  22. short intoken_service;        /* we don't handle reentrant calls, error() can be fatal */
  23.  
  24. token_service()
  25. {
  26.     struct token * theact;
  27.     struct winds ** conp = conns;
  28.     struct winds * conend = &conp[conncount];
  29.     register struct winds * twp;
  30.     extern short asciiflush;
  31.     
  32.     if (intoken_service)
  33.         return;
  34.     intoken_service = TRUE;
  35.     
  36.     /* TODO MULTI go through window list to see who needs service */
  37.     while (conp < conend) {
  38.         twp = *conp++;
  39.         if (twp == NULL)
  40.             continue;
  41.                 
  42.         if (twp->q_cnt == 0 || twp->delaytokens)
  43.             /* no input tokens waiting, or we should hold tokens for this window... */
  44.             continue;
  45.             
  46.         getcontext(twp);
  47.         while (!twp->delaytokens && twp->q_cnt > 0) {
  48.             theact = getaction();
  49.             if ((*twp->dotoken)(theact)) {
  50.                 ungetaction(theact);
  51.                 break;
  52.             }
  53.         }
  54.         if (twp->emwindow) {
  55.             /* if the session has a window, fix the macro flag */
  56.             if (!twp->macroexecuting) {
  57.                 if (twp->q_cnt > 0) {
  58.                     /* invert the macro flag */
  59.                     twp->macroexecuting = TRUE;
  60.                     /* InvalRect(&twp->macrorect);
  61.                     */
  62.                     showmacroflag();
  63.                         /* show inverse macro flag to indicate stuff left on
  64.                             queue which can still be cancelled... */
  65.                 }
  66.             }
  67.             else {
  68.                 if (twp->q_cnt <= 0) {
  69.                     /* reset the flag */
  70.                     twp->macroexecuting = FALSE;
  71.                     if (emdp->dokeymacros)
  72.                         showmacroflag();
  73.                     else
  74.                         clrmacroflag();
  75.                     /* InvalRect(&twp->macrorect);
  76.                     */
  77.                 }
  78.             }
  79.         }
  80.         if (asciiflush) {
  81.             /* flush the output buffers if called for, only need with ascii */
  82.             asciiflush = FALSE;
  83.             (*twp->putflush)();
  84.         }
  85.         twp->modflg = modflg;        /* must update in case state changed */
  86.     }
  87.     intoken_service = FALSE;
  88. }
  89.  
  90.  
  91. /* preserves the current context over a call to token_service() */
  92.  
  93. bkrd_token_service()
  94. {
  95.     struct winds * oemdp;
  96.  
  97.     oemdp = emdp;
  98.     token_service();
  99.     
  100.     getcontext(oemdp);    /* restore context, since it might have changed */
  101. }
  102.  
  103. /* reset the flag that holds token interpretation */
  104.  
  105. resumetokens(twp)
  106. struct winds * twp;
  107. {
  108.     twp->delaytokens = FALSE;
  109. }
  110.  
  111.  
  112. /* abort processing after match failure */
  113.  
  114. abortmatch(twp)
  115. struct winds * twp;
  116. {
  117.     struct winds * oemdp;
  118.     
  119.     oemdp = emdp;            
  120.     emdp = twp;            /* fix the data context for token processing */
  121.     
  122.     emdp->delaytokens = FALSE;
  123.     flushtokenmatch();
  124.     
  125.     emdp = oemdp;
  126. }
  127.  
  128.  
  129. /* the standard token handler, for tokens any emulator will need to handle */
  130.  
  131. stdtoken(tkptr)
  132. struct token *tkptr;
  133. {
  134.     struct token *wtoken;
  135.                 
  136.     switch (tkptr->class) {
  137.         case RSLT_SCOPY: {
  138.             rlincopy(tkptr->entry);
  139.             break;
  140.         }
  141.         case RSLT_DELAY: {
  142.             /* delay input for # of seconds specified by token entry */
  143.             emdp->delaytokens = TRUE;
  144.             tm_set((int) tkptr->entry, resumetokens, emdp, emdp->token_tm);
  145.             break;
  146.         }
  147.         case RSLT_MATCH: {
  148.             /* wait until a match is found in the input stream */
  149.             emdp->delaytokens = TRUE;
  150.             emdp->matchinput = TRUE;
  151.             tokenloop(-1);        /* establish eternal loop */
  152.             if (tkptr->entry != 255)
  153.                 /* time out on wait unless user specifies 255 */
  154.                 tm_set((int) tkptr->entry, abortmatch, emdp, emdp->token_tm);
  155.             break;
  156.         }
  157.         case RSLT_EMC:   {
  158.             /* emulator action key */
  159.             switch(tkptr->entry) {
  160.                 case EM_FILLCLOSE: {
  161.                     fillwindclose();
  162.                     break;
  163.                 }
  164.                 case EM_RESTORE: {
  165.                     /* restore line 25 -- used by hostconncomplete() */
  166.                     reset25(emdp);
  167.                     break;
  168.                 }
  169.                 case EM_HIDE: {
  170.                     emdp->emdisable = TRUE;
  171.                     /* make sure cursor is visible */
  172.                     SetCursor(&arrow); 
  173.                     showcursor(); 
  174.                     break;
  175.                 }
  176.                 case EM_ALTMACRO: {
  177.                     emdp->keyaltset = TRUE;
  178.                     /* InvalRect(&emdp->dubshiftrect); */
  179.                     if (emdp->dokeymacros)
  180.                         showaltmacro();
  181.                     break;
  182.                 }
  183.                 case EM_NORMMACRO: {
  184.                     emdp->keyaltset = FALSE;
  185.                     /* InvalRect(&emdp->dubshiftrect); */
  186.                     if (emdp->dokeymacros)
  187.                         clraltmacro();
  188.                     break;
  189.                 }
  190.                 case EM_CLOSE: {
  191.                     /* close the session */
  192.                     docloseconn();
  193.                     break;
  194.                 }
  195.                 case EM_SHOW: {
  196.                     emdp->emdisable = FALSE;
  197.                     /* (*emdp->screen_upd)(); */
  198.                     break;
  199.                 }
  200. #ifdef USETEXTWINDOWS
  201.                 case EM_EDIT: {
  202.                     selectwindow(emdp->textwindow);
  203.                     ShowWindow(emdp->textwindow);
  204.                     break;
  205.                 }
  206.                 case EM_TERM: {
  207.                     selectwindow(emdp->emwindow);
  208.                     break;
  209.                 }
  210.                 case EM_LITERAL: {
  211.                     if (emdp->emliteral)
  212.                         emdp->emliteral = FALSE;
  213.                     else
  214.                         emdp->emliteral = TRUE;
  215.                         /* set the ASCII emulators to pass all characters... */
  216.                     break;
  217.                 }
  218.                 case EM_TRYDSDRAW:  {
  219.                     /* toggle fast drawing mode */
  220.                     trydsdraw = !trydsdraw;
  221.                     testdsall();
  222.                     break;
  223.                 }
  224.                 case EM_TRACK:  {
  225.                     /* toggle sending of cursor positioning sequences with mouse */
  226.                     emdp->notrackcurs = !emdp->notrackcurs;
  227.                     break;
  228.                 }
  229. #endif
  230.                 default:
  231.                     entryerr(tkptr);
  232.             }
  233.             break;
  234.         }
  235.         case RSLT_LOOP:   {
  236.             /* emulator action key */
  237.             if (tkptr->entry == 255)
  238.                 /* loop forever */
  239.                 tokenloop(-1);
  240.             else
  241.                 tokenloop(tkptr->entry);
  242.             break;
  243.         }
  244.         case RSLT_FILE: {
  245.             switch (tkptr->entry) {
  246.                 case RF_SAVE:
  247.                 case RF_SAVEAS:
  248.                 case RF_APPEND:
  249.                 case RF_APPENDTO: {
  250.                     savetext(tkptr->entry);
  251.                     if (edresetselect)
  252.                         selreset(emdp);
  253.                         
  254.                     break;
  255.                 }
  256.                 case RF_PRINTDRAFT: {
  257.                     printtext(tkptr->entry, FALSE);
  258.                     if (edresetselect)
  259.                         selreset(emdp);
  260.                         
  261.                     break;
  262.                 }
  263.                 case RF_PRINTTEXT:
  264.                 case RF_PRINTSCREEN:
  265.                 case RF_PRINTSCRAP: {
  266.                     QDprinttext(tkptr->entry, FALSE);
  267.                     if (edresetselect)
  268.                         selreset(emdp);
  269.                         
  270.                     break;
  271.                 }
  272.                 case RF_NAME: {
  273. #ifdef RF_NAMEDONE
  274.                     int namecount = 0;
  275.                     
  276.                     while (twp->q_cnt > 0) {
  277.             
  278.                         theact = getaction();
  279.                         if ((*twp->dotoken)(theact)) {
  280.                             ungetaction(theact);
  281.                             break;
  282.                         }
  283.                     }
  284. #endif
  285.                     break;
  286.                 }
  287.             }
  288.             break;
  289.         }
  290.         case RSLT_SEL1: {
  291.             emdp->nselystart = tkptr->entry;
  292.             break;
  293.         }
  294.         case RSLT_SEL2: {
  295.             emdp->nselxstart = tkptr->entry;
  296.             break;
  297.         }
  298.         case RSLT_SEL3: {
  299.             emdp->nselyend = tkptr->entry;
  300.             break;
  301.         }
  302.         case RSLT_SEL4:
  303.         {
  304.             emdp->nselxend = tkptr->entry;
  305.             /* a selection has presumably now been defined */
  306.             
  307.             selreset(emdp);
  308.             selset(emdp->nselystart, emdp->nselxstart, emdp->nselyend, emdp->nselxend);
  309.  
  310.             selinvert(emdp);
  311.             emdp->selrectvis = TRUE;
  312.  
  313.             emdp->nselystart = 0;
  314.             emdp->nselxstart = 0;
  315.             emdp->nselyend = 0;
  316.             emdp->nselxend = 0;
  317.             break;
  318.         }
  319.         case RSLT_WIND: {
  320.             /* select the window corresponding to the ith entry in the menu */
  321.             windmenuselect((short) tkptr->entry);
  322.             break;
  323.         }
  324.         default: {
  325.             return(-1);
  326.         }
  327.     }
  328.     return(0);    
  329. }
  330.  
  331.  
  332. stdedit(action)
  333. unsigned char action;
  334. {
  335.     long len;
  336.     
  337.     switch (action) {
  338.         case ED_STDMODE: {
  339.             emdp->copytable = FALSE;
  340.             break;
  341.         }
  342.         case ED_TABLEMODE: {
  343.             /* elide tabs */
  344.             emdp->copytable = TRUE;
  345.             break;
  346.         }
  347.         case ED_WORDSELECT: {
  348.             /* select the word around the cursor position */
  349.             wordselect();
  350.             break;
  351.         }
  352.         case ED_SELRESET: {
  353.             if (emwindow) {
  354.                 selreset(emdp);
  355.             }
  356.             break;
  357.         }
  358.         case ED_SELALL: {
  359.             if (emwindow) {
  360. #ifdef DOTEXTEDIT
  361. /* macros should probably not muck with the TE window */
  362.                 if (emdp->edit) {
  363.                     tesetsel( (long) 0, (long) (*emdp->texthand)->teLength, emdp->texthand);
  364.                 }
  365.                 else {
  366. #endif
  367.                     selreset(emdp);
  368.                     selset(0, 0, 24, 0);
  369.                     selinvert(emdp);
  370.                     emdp->selrectvis = TRUE;
  371. #ifdef DOTEXTEDIT            
  372.                 }
  373. #endif
  374.             }
  375.             break;
  376.         }
  377.         case ED_CUT: {
  378. #ifdef DOTEXTEDIT            
  379.             if (emdp->edit) {
  380.                 textwcut(emdp);
  381.                 break;
  382.             }
  383. #endif
  384.             break;
  385.         }
  386. #ifdef USETEXTWINDOWS
  387.         case ED_APPEND: {
  388.             /* append selection to text window */
  389.             Ptr copyp;
  390.  
  391.             if ((len = getselection(©p)) == 0) {
  392.                 break;
  393.             }
  394.             if (!memtest(len, copyerr)) {
  395.                 /* not enough memory for operation */
  396.                 DisposPtr(copyp);
  397.                 break;
  398.             }
  399.             textwappend(copyp, len);
  400.             DisposPtr(copyp);
  401.             
  402.             if (edresetselect)
  403.                 selreset(emdp);
  404.                 
  405.             break;
  406.         }
  407. #else
  408.             /* when using the Clipboard you must hit SystemEdit() */
  409.         case ED_APPEND:
  410. #endif
  411.         case ED_COPY: 
  412.         {
  413.             /* copy the whole screen into the system scrap */
  414.             Ptr copyp;
  415. #ifdef DOTEXTEDIT            
  416.             if (emdp->edit) {
  417.                 /* we're in text editor, do it the easy way TODO should support append */
  418.                 textwcopy(emdp);
  419.                 break;
  420.             }
  421. #endif
  422.             if (mfpresent)
  423.                 /* make sure mf updates all client's scrap info */
  424.                 SystemEdit(EDCOPY - 1);
  425.  
  426.             if (!scrapzeroed) {
  427.                 /* zero the scrap the first time through */
  428.                 scrapzeroed = TRUE;
  429.                 scrapzero();
  430.             }
  431.             
  432.             if (action == ED_COPY)
  433.                 scrapzero();
  434.                 /* if scrap is not zeroed, putscrap will append */
  435.             
  436.             if ((len = getselection(©p)) == 0) {
  437.                 break;
  438.             }
  439.             
  440.             if (!memtest(len, copyerr)) {
  441.                 /* not enough memory for operation */
  442.                 DisposPtr(copyp);
  443.                 break;
  444.             }
  445. #ifdef USETEXTWINDOWS
  446.             PutScrap(len, 'TEXT', copyp);
  447. #else
  448.             puttextscrap(copyp, len);
  449. #endif
  450.             DisposPtr(copyp);
  451.  
  452.             if (edresetselect)
  453.                 selreset(emdp);
  454.                 
  455.             break;
  456.         }
  457.         case ED_PASTE: {
  458. #ifdef DOTEXTEDIT            
  459.             if (emdp->edit) {
  460.                 textwpaste(emdp);
  461.             }
  462.             else
  463. #endif
  464.                 return(TRUE);
  465.             break;
  466.         }
  467.         default: 
  468.             return(TRUE);
  469.     }
  470.     return(FALSE);
  471. }
  472.  
  473.  
  474. /* token error reporting routines */
  475. /* report an error in the class */
  476.  
  477. classerr(tkptr)
  478. struct token * tkptr;
  479. {
  480.     char badclassstr[140];
  481.  
  482.     sprintf(badclassstr, "Command '%c%c':  Unknown command class '%c' (decimal %u)", tkptr->class, tkptr->entry, tkptr->class, (int) tkptr->class);
  483.     SetDAFont((short) OURCHICAGO);
  484.     error(badclassstr);
  485.     SetDAFont((short) systemFont);
  486. }
  487.  
  488. /* report an error in the entry */
  489.  
  490. entryerr(tkptr)
  491. struct token * tkptr;
  492. {
  493.     char badclassstr[140];
  494.  
  495.     sprintf(badclassstr, "Command '%c%c':  Unknown command entry '%c' (decimal %u)", tkptr->class, tkptr->entry, tkptr->entry, (int) tkptr->entry);
  496.     SetDAFont((short) OURCHICAGO);
  497.     error(badclassstr);
  498.     SetDAFont((short) systemFont);
  499. }
  500.  
  501.  
  502. wordselect()
  503. {
  504.     register char * chp;
  505.     char * thep;
  506.     register char *  linestart;
  507.     register char *  lineend;
  508.     register unsigned char thechar;
  509.     short theypos;
  510.     short thexpos;
  511.     short startypos;            /* x,y starting and ending positions. y = column */
  512.     short startxpos;
  513.     short endypos;
  514.     short endxpos;
  515.     
  516.     selreset(emdp);
  517.     if (emdp->ibm_mode) {
  518.         thep = chp = cursor_ptr;
  519.         
  520.         startypos = (chp - scr_map) / emdp->linelength;
  521.         linestart = scr_map + (startypos * emdp->linelength);
  522.         lineend = linestart + emdp->linelength;
  523.  
  524.         while (chp >= emdp->scr_map && chp >= linestart) {
  525.             /* find a space at the left end */
  526.             thechar = *chp;
  527.             if (thechar < ATTR || thechar == IBMNULL || thechar == ' ')
  528.                 break;
  529.             --chp;
  530.         }
  531.         chp++;
  532.         startxpos = chp - (scr_map + (startypos * emdp->linelength));
  533.         
  534.         chp = thep;
  535.         while (chp < emdp->smap_end && chp < lineend) {
  536.             /* find a space at the right end */
  537.             thechar = *chp;
  538.             if (thechar < ATTR || thechar == IBMNULL || thechar == ' ')
  539.                 break;
  540.             chp++;
  541.         }
  542.         endypos = (chp - emdp->scr_map) / emdp->linelength;
  543.         endxpos = (chp - (scr_map + (endypos * emdp->linelength)));
  544.     }
  545.     else {
  546.         thep = chp = charp;
  547.         
  548.         startypos = (chp - &emdp->charr[0]) / emdp->linelength;
  549.         linestart = &emdp->charr[0] + (startypos * emdp->linelength);
  550.         lineend = linestart + emdp->linelength;
  551.  
  552.         while (chp >= &emdp->charr[0] && chp >= linestart) {
  553.             if (*chp == ' ')
  554.                 break;
  555.             --chp;
  556.         }
  557.         chp++;
  558.         startxpos = chp - (&emdp->charr[0] + (startypos * emdp->linelength));
  559.         
  560.         chp = thep;
  561.         while (chp < emdp->charrend && chp < lineend) {
  562.             if (*chp == ' ')
  563.                 break;
  564.             chp++;
  565.         }
  566.         endypos = (chp - &emdp->charr[0]) / emdp->linelength;
  567.         endxpos = chp - (&emdp->charr[0] + (endypos * emdp->linelength));
  568.     }
  569.     /* now invert the selection */
  570.     if (startypos == endypos && startxpos >= endxpos)
  571.         /* no selection */
  572.         return;
  573.         
  574.     selset(startypos, startxpos, endypos, endxpos);
  575.     selinvert(emdp);
  576.     emdp->selrectvis = TRUE;
  577. }
  578.  
  579.